﻿using Edge.Extensions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Collections.Generic;
using System;
using System.Collections;

namespace Edge.Tests
{
    
    
    /// <summary>
    ///This is a test class for CollectionExtensionsTest and is intended
    ///to contain all CollectionExtensionsTest Unit Tests
    ///</summary>
    [TestClass()]
    public class CollectionExtensionsTest
    {


        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion
        
        [TestMethod()]
        public void AddRangeTest()
        {
            List<string> items = new List<string>();
            items.Push("a");
            items.Push("b");
            items.Push("c");
            items.Push("d");
            int expected = 7;
            items.AddRange("e", "f", "g");
            int actual = items.Count;
            Assert.AreEqual(expected, actual);
        }

        [TestMethod()]
        public void AverageTest()
        {
            int[] array = new int[] { 1, 2, 3, 4, 5 };
            float expected = 3;
            float actual;
            actual = CollectionExtensions.Average(array);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod()]
        public void CombineTest()
        {
            int[] array1 = new int[] { 1, 2, 3 };
            int[] array2 = new int[] { 4, 5, 6 };
            int[] array3 = new int[] { 7, 8, 9 };
            bool expected = true;
            int[] combined = array1.Combine<int>(array2, array3);
            bool actual = false;
            if (combined[0] == 1 &&
                combined[1] == 2 &&
                combined[2] == 3 &&
                combined[3] == 4 &&
                combined[4] == 5 &&
                combined[5] == 6 &&
                combined[6] == 7 &&
                combined[7] == 8 &&
                combined[8] == 9)
            {
                actual = true;
            }
            Assert.AreEqual(expected, actual);
        }

        [TestMethod()]
        public void ContainsAtLeastTest()
        {
            List<int> list = new List<int>();
            list.Add(1);
            list.Add(2);
            list.Add(3);
            list.Add(4);
            int count = 2;
            bool expected = true;
            bool actual;
            actual = list.ContainsAtLeast<int>(count);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod()]
        public void GroupEveryTest()
        {
            List<int> list = new List<int>();
            for (int i = 0; i < 10; i++)
            {
                list.Add(i);
            }
            bool expected = true;
            bool actual = true;
            IEnumerable<int[]> newList = list.GroupEvery<int>(2);
            foreach (int[] item in newList)
            {
                if (item.Length != 2)
                {
                    actual = false;
                    break;
                }
            }
            Assert.AreEqual(expected, actual);
        }

        [TestMethod()]
        public void IndexOfTest()
        {
            List<string> items = new List<string>();
            items.Push("a");
            items.Push("b");
            items.Push("c");
            items.Push("d");
            string value = "c";
            int expected = 2;
            int actual;
            actual = items.IndexOf<string>(value);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod()]
        public void IndexOfTest2()
        {
            List<int> items = new List<int>();
            items.Push(1);
            items.Push(2);
            items.Push(3);
            items.Push(4);
            int value = 3;
            int expected = 2;
            int actual;
            actual = items.IndexOf<int>(value, EqualityComparer<int>.Default);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod()]
        public void IndexOfTest3()
        {
            List<int> items = new List<int>();
            items.Push(1);
            items.Push(2);
            items.Push(3);
            items.Push(1);
            items.Push(5);
            int value = 1;
            int expected = 3;
            int actual;
            actual = items.IndexOf<int>(value, 2);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod()]
        public void IndexOfTest4()
        {
            List<int> items = new List<int>();
            items.Push(1);
            items.Push(2);
            items.Push(3);
            items.Push(1);
            items.Push(5);
            int value = 1;
            int expected = 3;
            int actual;
            actual = items.IndexOf<int>(value, 2, EqualityComparer<int>.Default);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod()]
        public void IndexOfNextContainingTest()
        {
            List<string> items = new List<string>();
            items.Push("Hello, ");
            items.Push("World!");
            items.Push("How ");
            items.Push("are ");
            items.Push("you?");
            string value = "re";
            int startIndex = 1;
            int expected = 3;
            int actual;
            actual = items.IndexOfNextContaining(value, startIndex);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod()]
        public void IndexOfPrevious()
        {
            List<string> items = new List<string>();
            items.Push("a");
            items.Push("b");
            items.Push("c");
            items.Push("d");
            string value = "b";
            int startIndex = 3;
            int expected = 1;
            int actual;
            actual = items.IndexOfPrevious(value, startIndex);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod()]
        public void IndexOfPreviousContainingTest()
        {
            List<string> items = new List<string>();
            items.Push("Hello, ");
            items.Push("World!");
            items.Push("How ");
            items.Push("are ");
            items.Push("you?");
            string value = "rld";
            int startIndex = 3;
            int expected = 1;
            int actual;
            actual = items.IndexOfPreviousContaining(value, startIndex);
            Assert.AreEqual(expected, actual);
        }

        [TestMethod()]
        public void IsNullOrEmptyTest()
        {
            Array array = new string[] { };
            bool expected = true;
            bool actual;
            actual = array.IsNullOrEmpty();
            Assert.AreEqual(expected, actual);
        }

        [TestMethod()]
        public void IsNullOrEmptyTest2()
        {
            ArrayList list = new ArrayList();
            bool expected = true;
            bool actual;
            actual = list.IsNullOrEmpty();
            Assert.AreEqual(expected, actual);
        }

        [TestMethod()]
        public void RemoveDuplicatesTest()
        {
            string[] array = new string[] { "test1", "test2", "test1" };
            int expected = 2;
            int actual;
            actual = array.RemoveDuplicates().Length;
            Assert.AreEqual(expected, actual);
        }

        [TestMethod()]
        public void SliceTest()
        {
            int[] array = new int[] { 1, 2, 3, 4, 5 };
            int start = 1;
            int end = 3;
            int expected = 3;
            int actual;
            actual = array.Slice<int>(start, end)[1];
            Assert.AreEqual(expected, actual);
        }

        [TestMethod()]
        public void PopTest()
        {
            var list = new List<int>();
            for (int i = 1; i <= 10; i++)
            {
                list.Push(i);
            }

            int expected = 10;
            int actual;
            actual = list.Pop<int>();
            Assert.AreEqual(expected, actual);
        }

        [TestMethod()]
        public void PushTest()
        {
            var list = new List<int>();
            for (int i = 1; i <= 7; i++)
            {
                list.Push(i);
            }

            int expected = 7;
            int actual;
            actual = list.Pop<int>();
            Assert.AreEqual(expected, actual);
        }
    }
}
